home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #2 / Amiga Plus CD - 2004 - No. 02.iso / AmiSoft / Dev / misc / WHDLoad_dev.lha / WHDLoad / Src / sources / whdload / kickfs.s < prev    next >
Encoding:
Text File  |  2003-09-02  |  27.8 KB  |  1,271 lines

  1. ;*---------------------------------------------------------------------------
  2. ;  :Modul.    kickfs.s
  3. ;  :Contents.    filesystem handler for kick emulation under WHDLoad
  4. ;  :Author.    Wepl, JOTD
  5. ;  :Version.    $Id: kickfs.s 1.12 2003/09/01 21:13:57 wepl Exp wepl $
  6. ;  :History.    17.04.02 separated from kick13.s
  7. ;        02.05.02 _cb_dosRead added
  8. ;        09.05.02 symbols moved to the top for Asm-One/Pro
  9. ;        04.03.03 ACTION_COPY_DIR fixed, wb double click works now
  10. ;             deleting of directories works clean
  11. ;             changes by JOTD merged
  12. ;        04.04.03 various changes for kick31
  13. ;        11.07.03 relative object names now supported (e.g. "dh0:s//c/info")
  14. ;        06.08.03 sanity check for provided locks added (DEBUG)
  15. ;        09.08.03 ACTION_CURRENT_VOLUME added (JOTD)
  16. ;        01.09.03 ACTION_EXAMINE_FH fixed (Psygore)
  17. ;  :Requires.    -
  18. ;  :Copyright.    Public Domain
  19. ;  :Language.    68000 Assembler
  20. ;  :Translator.    Barfly 2.9, Asm-Pro 1.16, PhxAss 4.38
  21. ;  :To Do.    more dos packets (maybe)
  22. ;---------------------------------------------------------------------------*
  23.  
  24.     INCLUDE    lvo/expansion.i
  25.     INCLUDE    dos/dosextens.i
  26.     INCLUDE    dos/filehandler.i
  27.     INCLUDE    exec/resident.i
  28.     INCLUDE    libraries/configvars.i
  29.     INCLUDE    libraries/expansionbase.i
  30.  
  31. ;---------------------------------------------------------------------------*
  32. ;
  33. ; BootNode
  34. ; 08 LN_TYPE = NT_BOOTNODE
  35. ; 0a LN_NAME -> ConfigDev
  36. ;        10 cd_Rom+er_Type = ERTF_DIAGVALID
  37. ;        1c cd_Rom+er_Reserved0c -> DiagArea
  38. ;                       00 da_Config = DAC_CONFIGTIME
  39. ;                       06 da_BootPoint -> .bootcode
  40. ;                       0e da_SIZEOF
  41. ;        44 cd_SIZEOF
  42. ; 10 bn_DeviceNode -> DeviceNode (exp.MakeDosNode)
  43. *              04 dn_Type = 2
  44. ;              24 dn_SegList -> .seglist
  45. ;              2c dn_SIZEOF
  46. ; 14 bn_SIZEOF
  47.  
  48.     IFND HD_Cyls
  49. HD_Cyls            = 80
  50.     ENDC
  51. HD_Surfaces        = 2
  52. HD_BlocksPerTrack    = 11
  53. HD_NumBlocksRes        = 2
  54. HD_NumBlocks        = HD_Cyls*HD_Surfaces*HD_BlocksPerTrack-HD_NumBlocksRes
  55. HD_NumBlocksUsed    = HD_NumBlocks/2
  56. HD_BytesPerBlock    = 512
  57. HD_NumBuffers        = 5
  58.  
  59.     ;file locking is not implemented! no locklist is used
  60.     ;fl_Key is used for the filename which makes it impossible to compare two locks for equality!
  61.  
  62.     STRUCTURE MyLock,fl_SIZEOF
  63.         LONG    mfl_pos            ;position in file
  64.         STRUCT    mfl_fib,fib_Reserved    ;FileInfoBlock
  65.     IFD IOCACHE
  66.         LONG    mfl_cpos        ;fileoffset cache points to
  67.         LONG    mfl_clen        ;amount data in cache (valid only on write cache)
  68.         LONG    mfl_iocache
  69.     ENDC
  70.         LABEL    mfl_SIZEOF
  71.  
  72. ;---------------------------------------------------------------------------*
  73.  
  74.         movem.l    d0-a6,-(a7)
  75.  
  76.         moveq    #ConfigDev_SIZEOF,d0
  77.         move.l    #MEMF_CLEAR,d1
  78.         move.l    (4),a6
  79.         jsr    (_LVOAllocMem,a6)
  80.         move.l    d0,a5                ;A5 = ConfigDev
  81.         bset    #ERTB_DIAGVALID,(cd_Rom+er_Type,a5)
  82.         lea    (.diagarea,pc),a0
  83.         move.l    a0,(cd_Rom+er_Reserved0c,a5)
  84.  
  85.         lea    (.expansionname,pc),a1
  86.         jsr    (_LVOOldOpenLibrary,a6)
  87.         move.l    d0,a4                ;A4 = expansionbase
  88.  
  89.         lea    (.parameterPkt+8,pc),a0
  90.         lea    (.devicename,pc),a1
  91.         move.l    a1,-(a0)
  92.         lea    (.handlername,pc),a1
  93.         move.l    a1,-(a0)
  94.         exg.l    a4,a6
  95.         jsr    (_LVOMakeDosNode,a6)
  96.         exg.l    a4,a6
  97.         move.l    d0,a3                ;A3 = DeviceNode
  98.         lea    (.seglist,pc),a1
  99.         move.l    a1,d1
  100.         lsr.l    #2,d1
  101.         move.l    d1,(dn_SegList,a3)
  102.         moveq    #-1,d0
  103.         move.l    d0,(dn_GlobalVec,a3)        ;no BCPL shit
  104.  
  105.         moveq    #BootNode_SIZEOF,d0
  106.         move.l    #MEMF_CLEAR,d1
  107.         jsr    (_LVOAllocMem,a6)
  108.         move.l    d0,a1                ;BootNode
  109.         move.b    #NT_BOOTNODE,(LN_TYPE,a1)
  110.         move.l    a5,(LN_NAME,a1)            ;ConfigDev
  111.         move.l    a3,(bn_DeviceNode,a1)
  112.  
  113.         lea    (eb_MountList,a4),a0
  114.         jsr    (_LVOEnqueue,a6)
  115.  
  116.         movem.l    (a7)+,d0-a6
  117.         rts
  118.  
  119. .diagarea    dc.b    DAC_CONFIGTIME        ;da_Config
  120.         dc.b    0            ;da_Flags
  121.         dc.w    0            ;da_Size
  122.         dc.w    0            ;da_DiagPoint
  123.         dc.w    .bootcode-.diagarea    ;da_BootPoint
  124.         dc.w    0            ;da_Name
  125.         dc.w    0            ;da_Reserved01
  126.         dc.w    0            ;da_Reserved02
  127.  
  128. .parameterPkt    dc.l    0            ;name of dos handler
  129.         dc.l    0            ;name of exec device
  130.         dc.l    0            ;unit number for OpenDevice
  131.         dc.l    0            ;flags for OpenDevice
  132.         dc.l    16            ;de_TableSize count following longwords
  133.         dc.l    HD_BytesPerBlock/4    ;de_SizeBlock longs per block
  134.         dc.l    0            ;de_SecOrg sector start, unused
  135.         dc.l    HD_Surfaces        ;de_Surfaces
  136.         dc.l    1            ;de_SectorPerBlock unused
  137.         dc.l    HD_BlocksPerTrack    ;de_BlocksPerTrack
  138.         dc.l    HD_NumBlocksRes        ;de_Reserved reserved blocks
  139.         dc.l    0            ;de_PreAlloc unused
  140.         dc.l    0            ;de_Interleave
  141.         dc.l    0            ;de_LowCyl
  142.         dc.l    HD_Cyls-1        ;de_HighCyl
  143.         dc.l    HD_NumBuffers        ;de_NumBuffers
  144.         dc.l    MEMF_PUBLIC        ;de_BufMemType
  145.         dc.l    MAXINT            ;de_MaxTransfer
  146.         dc.l    -1            ;de_Mask
  147.         dc.l    0            ;de_BootPri
  148.         dc.l    ID_DOS_DISK        ;de_DosType
  149.     ;    dc.l                ;de_Baud
  150.     ;    dc.l                ;de_Control
  151.     ;    dc.l                ;de_BootBlocks
  152.     EVEN
  153.  
  154. .bootcode    lea    (_dosname,pc),a1
  155.         jsr    (_LVOFindResident,a6)
  156.         move.l    d0,a0
  157.         move.l    (RT_INIT,a0),a0
  158.         jmp    (a0)            ;init dos.library
  159.  
  160.     CNOP 0,4
  161.         dc.l    16            ;segment length
  162. .seglist    dc.l    0            ;next segment
  163.  
  164.     ;get own message port
  165.         move.l    (4),a6            ;A6 = execbase
  166.         sub.l    a1,a1
  167.         jsr    (_LVOFindTask,a6)
  168.         move.l    d0,a1
  169.         lea    (pr_MsgPort,a1),a5    ;A5 = MsgPort
  170.  
  171.     ;init volume structure
  172.         lea    (.volumename,pc),a0
  173.         move.l    a0,d0
  174.         lsr.l    #2,d0
  175.         move.l    d0,-(a7)        ;dl_Name
  176.         clr.l    -(a7)            ;dl_unused
  177.         move.l    #ID_DOS_DISK,-(a7)    ;dl_DiskType (is normally 0!)
  178.         clr.l    -(a7)            ;dl_LockList
  179.         clr.l    -(a7)            ;dl_VolumeDate
  180.         clr.l    -(a7)            ;dl_VolumeDate
  181.         clr.l    -(a7)            ;dl_VolumeDate
  182.         clr.l    -(a7)            ;dl_Lock
  183.         move.l    a5,-(a7)        ;dl_Task (MsgPort)
  184.         move.l    #DLT_VOLUME,-(a7)    ;dl_Type
  185.         clr.l    -(a7)            ;dl_Next
  186.         move.l    a7,d0
  187.         lsr.l    #2,d0
  188.         move.l    d0,a3            ;A3 = Volume (BPTR)
  189.     ;add to the system
  190.         lea    (_dosname,pc),a1
  191.         jsr    (_LVOOldOpenLibrary,a6)
  192.         move.l    d0,a0
  193.         move.l    (dl_Root,a0),a0
  194.         move.l    (rn_Info,a0),a0
  195.         add.l    a0,a0
  196.         add.l    a0,a0
  197.         move.l    (di_DevInfo,a0),(dol_Next,a7)
  198.         move.l    a3,(di_DevInfo,a0)
  199.  
  200.         move.l    (_resload,pc),a2    ;A2 = resload
  201.  
  202.     ;fetch and reply startup message
  203.         move.l    a5,a0
  204.         jsr    (_LVOWaitPort,a6)
  205.         move.l    a5,a0
  206.         jsr    (_LVOGetMsg,a6)
  207.         move.l    d0,a4
  208.         move.l    (LN_NAME,a4),a4        ;A4 = DosPacket
  209.         move.l    (dp_Arg3,a4),a0        ;DeviceNode
  210.         add.l    a0,a0
  211.         add.l    a0,a0
  212.         move.l    a5,(dn_Task,a0)        ;signal: the handler is running
  213.         moveq    #DOSTRUE,d0        ;success
  214.         bra    .reply1
  215.  
  216.     ;loop on receiving new packets
  217. .mainloop    move.l    a5,a0
  218.         jsr    (_LVOWaitPort,a6)
  219.         move.l    a5,a0
  220.         jsr    (_LVOGetMsg,a6)
  221.         move.l    d0,a4
  222.         move.l    (LN_NAME,a4),a4        ;A4 = DosPacket
  223.  
  224.     ;find and call appropriate action
  225.         moveq    #0,d0
  226.         move.l    (dp_Type,a4),d2
  227.         lea    (.action,pc),a0
  228. .next        movem.w    (a0)+,d0-d1
  229.     IFD DEBUG
  230.         tst.l    d0
  231.         beq    _debug1            ;unknown packet
  232.     ENDC
  233.         cmp.w    d0,d2            ;this should be cmp.l
  234.         bne    .next
  235.         jmp    (.action,pc,d1.w)
  236.  
  237. ;---------------
  238. ; reply dos-packet
  239. ; IN:    D0 = res1
  240. ;    D1 = res2
  241.  
  242. .reply2        move.l    d1,(dp_Res2,a4)
  243.  
  244. ;---------------
  245. ; reply dos-packet
  246. ; IN:    D0 = res1
  247.  
  248. .reply1        move.l    d0,(dp_Res1,a4)
  249.         move.l    (dp_Port,a4),a0
  250.         move.l    (dp_Link,a4),a1
  251.         move.l    a5,(dp_Port,a4)
  252.         jsr    (_LVOPutMsg,a6)
  253.         bra    .mainloop
  254.  
  255. .action        dc.w    ACTION_CURRENT_VOLUME,.a_current_volume-.action        ;7    7
  256.         dc.w    ACTION_LOCATE_OBJECT,.a_locate_object-.action        ;8    8
  257.         dc.w    ACTION_FREE_LOCK,.a_free_lock-.action            ;f    15
  258.         dc.w    ACTION_DELETE_OBJECT,.a_delete_object-.action        ;10    16
  259.         dc.w    ACTION_COPY_DIR,.a_copy_dir-.action            ;13    19
  260.         dc.w    ACTION_SET_PROTECT,.a_set_protect-.action        ;15    21
  261.         dc.w    ACTION_CREATE_DIR,.a_create_dir-.action            ;16    22
  262.         dc.w    ACTION_EXAMINE_OBJECT,.a_examine_object-.action        ;17    23
  263.         dc.w    ACTION_EXAMINE_NEXT,.a_examine_next-.action        ;18    24
  264.         dc.w    ACTION_DISK_INFO,.a_disk_info-.action            ;19    25
  265.         dc.w    ACTION_INFO,.a_info-.action                ;1a    26
  266.         dc.w    ACTION_FLUSH,.a_flush-.action                ;1b    27
  267.         dc.w    ACTION_PARENT,.a_parent-.action                ;1d    29
  268.         dc.w    ACTION_INHIBIT,.a_inhibit-.action            ;1f    31
  269.         dc.w    ACTION_READ,.a_read-.action                ;52    82
  270.         dc.w    ACTION_WRITE,.a_write-.action                ;57    87
  271.         dc.w    ACTION_FINDUPDATE,.a_findupdate-.action            ;3ec    1004
  272.         dc.w    ACTION_FINDINPUT,.a_findinput-.action            ;3ed    1005
  273.         dc.w    ACTION_FINDOUTPUT,.a_findoutput-.action            ;3ee    1006
  274.         dc.w    ACTION_END,.a_end-.action                ;3ef    1007
  275.         dc.w    ACTION_SEEK,.a_seek-.action                ;3f0    1008
  276.     IFGT KICKVERSION-36
  277.         dc.w    ACTION_SAME_LOCK,.a_same_lock-.action            ;28    40
  278.         dc.w    ACTION_FH_FROM_LOCK,.a_fh_from_lock-.action        ;402    1026
  279.         dc.w    ACTION_IS_FILESYSTEM,.a_is_filesystem-.action        ;403    1027
  280.         dc.w    ACTION_EXAMINE_ALL,.a_examine_all-.action        ;409    1033
  281.         dc.w    ACTION_EXAMINE_FH,.a_examine_fh-.action            ;40A    1034
  282.     ENDC
  283.         dc.w    0
  284.  
  285.     ; conventions for action functions:
  286.     ; IN:    a2 = resload
  287.     ;    a3 = BPTR volume node
  288.     ;    a4 = packet
  289.     ;    a5 = MsgPort
  290.     ;    a6 = execbase
  291.  
  292. ;---------------
  293.  
  294. .a_current_volume
  295.         move.l    a3,d0            ;volume
  296.         moveq    #0,d1            ;unit number
  297.         bra    .reply2
  298.     
  299. ;---------------
  300.  
  301. .a_locate_object
  302.         bsr    .getarg1        ;lock
  303.         move.l    d7,d0
  304.         bsr    .getarg2        ;name
  305.         move.l    d7,d1
  306.         move.l    (dp_Arg3,a4),d2        ;mode
  307.         bsr    .lock
  308.         lsr.l    #2,d0            ;APTR > BPTR
  309.         bne    .reply1
  310.         bra    .reply2
  311.  
  312. ;---------------
  313.  
  314. .a_free_lock    bsr    .getarg1
  315.         move.l    d7,d0
  316.         bsr    .unlock
  317.         moveq    #DOSTRUE,d0
  318.         bra    .reply1
  319.  
  320. ;---------------
  321.  
  322. .a_delete_object
  323.         bsr    .getarg1        ;lock
  324.         move.l    d7,d0
  325.         bsr    .getarg2        ;name
  326.         move.l    d7,d1
  327.         move.l    #ACCESS_READ,d2
  328.         bsr    .lock
  329.         move.l    d0,d7            ;d7 = new lock
  330.         beq    .reply2
  331.         move.l    d0,a0
  332.         tst.l    (mfl_fib+fib_DirEntryType,a0)
  333.         bmi    .delete_do
  334.     ;a directory
  335.         lea    (mfl_fib,a0),a0
  336.         jsr    (resload_ExNext,a2)
  337.         tst.l    d0
  338.         bne    .delete_dirnotempty
  339.         move.l    d7,a0
  340. .delete_do    move.l    (fl_Key,a0),a0
  341.         jsr    (resload_DeleteFile,a2)
  342.         move.l    d7,d0
  343.         bsr    .unlock
  344.         moveq    #DOSTRUE,d0
  345.         bra    .reply1
  346.  
  347. .delete_dirnotempty
  348.         move.l    d7,d0
  349.         bsr    .unlock
  350.         moveq    #DOSFALSE,d0
  351.         move.l    #ERROR_DIRECTORY_NOT_EMPTY,d1
  352.         bra    .reply2
  353.  
  354. ;---------------
  355.  
  356. .a_copy_dir    bsr    .getarg1
  357.     IFD DEBUG
  358.         beq    _debug2
  359.     ENDC
  360.     ;copy name
  361.         move.l    d7,a0            ;a0 = APTR lock
  362.     IFD DEBUG
  363.         cmp.l    (fl_Task,a0),a5
  364.         bne    _debug4
  365.     ENDC
  366.         move.l    (fl_Key,a0),a0        ;name
  367.         move.l    -(a0),d0
  368.         moveq    #0,d1
  369.         jsr    (_LVOAllocMem,a6)
  370.         move.l    d0,d2            ;d2 = new name
  371.         beq    .copy_dir_nm
  372.         move.l    d7,a0
  373.         move.l    (fl_Key,a0),a0
  374.         move.l    d2,a1
  375.         move.l    -(a0),d0        ;length
  376. .copy_dir_cpy    move.l    (a0)+,(a1)+
  377.         subq.l    #4,d0
  378.         bhi    .copy_dir_cpy
  379.     ;copy lock
  380.         move.l    #mfl_SIZEOF,d0
  381.         move.l    #MEMF_CLEAR,d1
  382.         jsr    (_LVOAllocMem,a6)
  383.         tst.l    d0
  384.         beq    .copy_dir_nm2
  385.     ;fill lock structure
  386.         move.l    d7,a0
  387.         move.l    d0,a1
  388.         move.l    (a0)+,(a1)+        ;fl_Link
  389.         addq.l    #4,d2
  390.         move.l    d2,(a1)+        ;fl_Key (name)
  391.         addq.l    #4,a0
  392.         move.l    (a0)+,(a1)+        ;fl_Access
  393.         move.l    (a0)+,(a1)+        ;fl_Task (MsgPort)
  394.         move.l    (a0)+,(a1)+        ;fl_Volume
  395.         lsr.l    #2,d0            ;lock
  396.         bra    .reply1
  397.  
  398. .copy_dir_nm2    move.l    d2,a1
  399.         move.l    (a1),d0
  400.         jsr    (_LVOFreeMem,a6)
  401. .copy_dir_nm    moveq    #DOSFALSE,d0
  402.         move.l    #ERROR_NO_FREE_STORE,d1
  403.         bra    .reply2
  404.  
  405. ;---------------
  406.  
  407. .a_create_dir    moveq    #0,d0
  408.         move.l    #ERROR_DISK_FULL,d1
  409.         bra    .reply2
  410.  
  411. ;---------------
  412.  
  413.     IFGT KICKVERSION-36
  414. .a_examine_fh    move.l    (dp_Arg1,a4),a0        ;lock
  415.         bra    .a_examine
  416.     ENDC
  417.  
  418. .a_examine_object
  419.         bsr    .getarg1
  420.         move.l    d7,a0            ;a0 = APTR lock
  421.  
  422. .a_examine    bsr    .getarg2        ;d7 = APTR fib
  423.         move.l    a0,d0
  424.         beq    .examine_root
  425.     ;copy whdload's examine result
  426.         add.w    #mfl_fib,a0
  427.         move.l    d7,a1
  428.         moveq    #fib_Reserved/4-1,d0
  429. .examine_fib    move.l    (a0)+,(a1)+
  430.         dbf    d0,.examine_fib
  431.     ;adjust
  432. .examine_adj
  433.     ;convert CSTR -> BSTR
  434.         move.l    d7,a1
  435.         lea    (fib_FileName,a1),a0
  436.         bsr    .bstr
  437.         lea    (fib_Comment,a1),a0
  438.         bsr    .bstr
  439.     ;return
  440.         moveq    #DOSTRUE,d0
  441.         bra    .reply1
  442.  
  443.     ;special handling of NULL lock
  444. .examine_root    clr.l    -(a7)
  445.         move.l    a7,a0
  446.         move.l    d7,a1
  447.         jsr    (resload_Examine,a2)
  448.         addq.l    #4,a7
  449.         lea    (.volumename+1,pc),a0    ;CPTR
  450.         move.l    d7,a1
  451.         add.w    #fib_FileName,a1
  452. .examine_root2    move.b    (a0)+,(a1)+
  453.         bne    .examine_root2
  454.         bra    .examine_adj
  455.  
  456. ;---------------
  457.  
  458. .a_examine_next    bsr    .getarg2
  459.         move.l    d7,a0            ;a0 = APTR fib
  460.         jsr    (resload_ExNext,a2)
  461.         move.l    d7,a1
  462.     ;convert CSTR -> BSTR
  463.         lea    (fib_FileName,a1),a0
  464.         bsr    .bstr
  465.         lea    (fib_Comment,a1),a0
  466.         bsr    .bstr
  467.         bra    .reply2
  468.  
  469. ;---------------
  470.  
  471. .a_info        bsr    .getarg2
  472.         bra    .a_disk_info_1
  473.  
  474. ;---------------
  475.  
  476. .a_disk_info    bsr    .getarg1
  477. .a_disk_info_1    move.l    d7,a0
  478.         clr.l    (a0)+            ;id_NumSoftErrors
  479.         clr.l    (a0)+            ;id_UnitNumber
  480.         move.l    #ID_VALIDATED,(a0)+    ;id_DiskState
  481.         move.l    #HD_NumBlocks,(a0)+    ;id_NumBlocks
  482.         move.l    #HD_NumBlocksUsed,(a0)+    ;id_NumBlocksUsed
  483.         move.l    #HD_BytesPerBlock,(a0)+    ;id_BytesPerBlock
  484.         move.l    #ID_DOS_DISK,(a0)+    ;id_DiskType
  485.         move.l    a3,(a0)+        ;id_VolumeNode
  486.         clr.l    (a0)+            ;id_InUse
  487.  
  488. ;---------------
  489.  
  490. .a_is_filesystem
  491. .a_set_protect
  492. .a_flush
  493. .a_inhibit    moveq    #DOSTRUE,d0
  494.         bra    .reply1
  495.  
  496. ;---------------
  497.  
  498. .a_parent    bsr    .getarg1
  499.         beq    .parent_root
  500.         move.l    d7,a0            ;d7 = lock
  501.     IFD DEBUG
  502.         cmp.l    (fl_Task,a0),a5
  503.         bne    _debug4
  504.     ENDC
  505.         move.l    (fl_Key,a0),a0
  506.         tst.b    (a0)
  507.         beq    .parent_root
  508.     ;get string length
  509.         moveq    #-1,d0
  510. .parent_strlen    addq.l    #1,d0
  511.         tst.b    (a0)+
  512.         bne    .parent_strlen        ;d0 = strlen
  513.     ;search for "/"
  514.         move.l    d7,a0
  515.         move.l    (fl_Key,a0),a0
  516.         lea    (a0,d0.l),a1
  517. .parent_search    cmp.b    #"/",-(a1)
  518.         beq    .parent_slash
  519.         cmp.l    a0,a1
  520.         bne    .parent_search
  521.     ;no slash found, so we are locking root
  522.     ;lock the parent directory
  523. .parent_slash
  524.     ;build temporary bstr
  525.         move.l    a1,d0
  526.         sub.l    a0,d0            ;length
  527.         move.l    d0,d3
  528.         addq.l    #4,d3            ;+1 and align4
  529.         and.b    #$fc,d3
  530.         sub.l    d3,a7
  531.         move.l    a7,a1
  532.         move.b    d0,(a1)+
  533. .parent_cpy    move.b    (a0)+,(a1)+
  534.         subq.l    #1,d0
  535.         bhi    .parent_cpy
  536.     ;lock it
  537.         moveq    #0,d0            ;lock
  538.         move.l    a7,d1            ;name
  539.         move.l    #ACCESS_READ,d2        ;mode
  540.         bsr    .lock
  541.         add.l    d3,a7
  542.         lsr.l    #2,d0            ;APTR > BPTR
  543.         bne    .reply1
  544.         bra    .reply2
  545.     ;that is a special case!
  546. .parent_root    moveq    #0,d0
  547.         moveq    #0,d1
  548.         bra    .reply2
  549.  
  550. ;---------------
  551.  
  552.     IFGT KICKVERSION-36
  553. .a_same_lock    bsr    .getarg1
  554.         move.l    d7,a0
  555.         bsr    .getarg2
  556.         move.l    d7,a1
  557.         move.l    a0,d0
  558.         beq    .samelock_zero
  559.     IFD DEBUG
  560.         cmp.l    (fl_Task,a0),a5
  561.         bne    _debug4
  562.     ENDC
  563.         move.l    (fl_Key,a0),a0
  564.         tst.b    (a0)
  565.         beq    .samelock_zero
  566.         move.l    a1,d0
  567.         beq    .samelock_neq
  568.     IFD DEBUG
  569.         cmp.l    (fl_Task,a1),a5
  570.         bne    _debug4
  571.     ENDC
  572.         move.l    (fl_Key,a1),a1
  573. .samelock_cmp    move.b    (a0)+,d0
  574.         cmp.b    (a1)+,d0
  575.         bne    .samelock_neq
  576.         tst.b    d0
  577.         bne    .samelock_cmp
  578. .samelock_equ    moveq    #DOSTRUE,d0
  579.         bra    .reply1
  580.  
  581. .samelock_zero    move.l    a1,d0
  582.         beq    .samelock_equ
  583.         move.l    (fl_Key,a1),a1
  584.         tst.b    (a1)
  585.         beq    .samelock_equ
  586. .samelock_neq    moveq    #0,d0
  587.         moveq    #0,d1
  588.         bra    .reply2
  589.     ENDC
  590.  
  591. ;---------------
  592.  
  593. .a_read        move.l    (dp_Arg1,a4),a0            ;a0 = APTR lock
  594.     IFD DEBUG
  595.         cmp.l    (fl_Task,a0),a5
  596.         bne    _debug4
  597.     ENDC
  598.         move.l    (dp_Arg3,a4),d3            ;d3 = readsize
  599.     IFD IOCACHE
  600.         moveq    #0,d4                ;d4 = readcachesize
  601.     ENDC
  602.         move.l    (mfl_pos,a0),d5            ;d5 = pos
  603.     ;correct readsize if necessary
  604.         move.l    (mfl_fib+fib_Size,a0),d2
  605.         sub.l    d5,d2                ;d2 = bytes left in file
  606.         cmp.l    d2,d3
  607.         bls    .read_ok
  608.         move.l    d2,d3                ;d3 = readsize
  609. .read_ok    tst.l    d3
  610.         beq    .read_end            ;eof
  611.         add.l    d3,(mfl_pos,a0)
  612.     IFD BOOTDOS
  613.     ;special files
  614.         move.l    (fl_Key,a0),a0            ;name
  615.         bsr    .specialfile
  616.         tst.l    d0
  617.         beq    .read_nospec
  618.         move.l    d0,a0
  619.         add.l    d5,a0                ;source
  620.         move.l    (dp_Arg2,a4),a1            ;destination
  621.         move.l    d3,d0
  622. .read_spec    move.b    (a0)+,(a1)+
  623.         subq.l    #1,d0
  624.         bne    .read_spec
  625.         bra    .read_end
  626. .read_nospec    move.l    (dp_Arg1,a4),a0
  627.     ENDC
  628.     IFND IOCACHE
  629.     ;read direct
  630.         move.l    d3,d0                ;length
  631.         move.l    d5,d1                ;offset
  632.         move.l    (fl_Key,a0),a0            ;name
  633.         move.l    (dp_Arg2,a4),a1            ;buffer
  634.         jsr    (resload_LoadFileOffset,a2)
  635.     ;finish
  636. .read_end    move.l    d3,d0                ;bytes read
  637.     IFD CBDOSREAD
  638.         movem.l    d0-a6,-(a7)
  639.         move.l    (dp_Arg1,a4),a0
  640.         move.l    (mfl_pos,a0),d1
  641.         sub.l    d0,d1                ;file pos
  642.         move.l    (fl_Key,a0),a0            ;name
  643.         move.l    (dp_Arg2,a4),a1            ;buffer
  644.         bsr    _cb_dosRead
  645.         movem.l    (a7)+,d0-a6
  646.     ENDC
  647.         bra    .reply1
  648.     ELSE
  649.         move.l    (mfl_cpos,a0),d6        ;d6 = cachepos
  650.         move.l    #IOCACHE,d7            ;d7 = IOCACHE
  651.     ;try from cache
  652.         tst.l    (mfl_iocache,a0)        ;buffer allocated?
  653.         beq    .read_1
  654.         cmp.l    d5,d6
  655.         bhi    .read_1
  656.         move.l    d7,d0
  657.         add.l    d6,d0
  658.         sub.l    d5,d0
  659.         bls    .read_1
  660.         move.l    d0,d4                ;d4 = readcachesize
  661.         cmp.l    d4,d3
  662.         bhi    .read_2
  663.         move.l    d3,d4
  664. .read_2        move.l    (mfl_iocache,a0),a0
  665.         add.l    d5,a0
  666.         sub.l    d6,a0                ;source
  667.         move.l    (dp_Arg2,a4),a1            ;destination
  668.         move.l    d4,d0
  669. .read_3        move.b    (a0)+,(a1)+
  670.         subq.l    #1,d0
  671.         bne    .read_3
  672.         add.l    d4,d5
  673.         sub.l    d4,d2
  674.         sub.l    d4,d3
  675.         beq    .read_end
  676.     ;decide if read through cache or direct
  677. .read_1        cmp.l    d2,d3
  678.         beq    .read_d                ;read remaining/complete file -> doesn't make sense to cache it
  679.         cmp.l    d7,d3
  680.         blo    .read_c
  681.     ;read direct
  682. .read_d        move.l    d3,d0                ;length
  683.         move.l    d5,d1                ;offset
  684.         move.l    (dp_Arg1,a4),a0
  685.         move.l    (fl_Key,a0),a0            ;name
  686.         move.l    (dp_Arg2,a4),a1            ;buffer
  687.         add.l    d4,a1
  688.         jsr    (resload_LoadFileOffset,a2)
  689.         bra    .read_end
  690.     ;read through cache
  691. .read_c
  692.     ;get memory if necessary
  693.         move.l    (dp_Arg1,a4),a0
  694.         move.l    (mfl_iocache,a0),d0
  695.         bne    .read_c1
  696.         move.l    d7,d0
  697.         moveq    #MEMF_ANY,d1
  698.         jsr    (_LVOAllocMem,a6)
  699.         move.l    (dp_Arg1,a4),a0
  700.         move.l    d0,(mfl_iocache,a0)
  701.         beq    .read_d
  702.     ;read into cache
  703. .read_c1    move.l    d0,a1                ;buffer
  704.         move.l    (mfl_fib+fib_Size,a0),d0
  705.         sub.l    d5,d0                ;length
  706.         cmp.l    d7,d0
  707.         bls    .read_c2
  708.         move.l    d7,d0                ;length
  709. .read_c2    move.l    d5,d1                ;offset
  710.         move.l    (fl_Key,a0),a0            ;name
  711.         jsr    (resload_LoadFileOffset,a2)
  712.         move.l    (dp_Arg1,a4),a0
  713.         move.l    d5,(mfl_cpos,a0)
  714.     ;copy from cache
  715.         move.l    (mfl_iocache,a0),a0        ;source
  716.         move.l    (dp_Arg2,a4),a1
  717.         add.l    d4,a1                ;destination
  718.         move.l    d3,d0
  719. .read_c3    move.b    (a0)+,(a1)+
  720.         subq.l    #1,d0
  721.         bne    .read_c3
  722.     ;finish
  723. .read_end    move.l    d3,d0
  724.         add.l    d4,d0
  725.     IFD CBDOSREAD
  726.         movem.l    d0-a6,-(a7)
  727.         move.l    (dp_Arg1,a4),a0
  728.         move.l    (mfl_pos,a0),d1
  729.         sub.l    d0,d1                ;file pos
  730.         move.l    (fl_Key,a0),a0            ;name
  731.         move.l    (dp_Arg2,a4),a1            ;buffer
  732.         bsr    _cb_dosRead
  733.         movem.l    (a7)+,d0-a6
  734.     ENDC
  735.         bra    .reply1
  736.     ENDC
  737.  
  738. ;---------------
  739.  
  740. .a_write    move.l    (dp_Arg1,a4),a0            ;APTR lock
  741.     IFD DEBUG
  742.         cmp.l    (fl_Task,a0),a5
  743.         bne    _debug4
  744.     ENDC
  745.     IFND IOCACHE
  746.         move.l    (dp_Arg3,a4),d0            ;len
  747.         move.l    (mfl_pos,a0),d1            ;offset
  748.         move.l    d1,d2
  749.         add.l    d0,d2
  750.         move.l    d2,(mfl_pos,a0)
  751.         cmp.l    (mfl_fib+fib_Size,a0),d2
  752.         bls    .write1
  753.         move.l    d2,(mfl_fib+fib_Size,a0)    ;new length
  754. .write1        move.l    (fl_Key,a0),a0            ;name
  755.         move.l    (dp_Arg2,a4),a1            ;buffer
  756.         jsr    (resload_SaveFileOffset,a2)
  757.         move.l    (dp_Arg3,a4),d0            ;bytes written
  758.         bra    .reply1
  759.     ELSE
  760.     ;set new pos and correct size if necessary
  761.         move.l    #IOCACHE,d4            ;d4 = IOCACHE
  762.         move.l    (dp_Arg2,a4),d5            ;d5 = buffer
  763.         move.l    (dp_Arg3,a4),d6            ;d6 = len
  764.         beq    .write_end
  765.         move.l    (mfl_pos,a0),d7            ;d7 = offset
  766.         move.l    d6,d0
  767.         add.l    d7,d0
  768.         move.l    d0,(mfl_pos,a0)
  769.         cmp.l    (mfl_fib+fib_Size,a0),d0
  770.         bls    .write_1
  771.         move.l    d0,(mfl_fib+fib_Size,a0)    ;new length
  772. .write_1
  773.     ;check if fits into cache
  774.         move.l    d4,d0
  775.         move.l    (mfl_cpos,a0),d1
  776.         add.l    (mfl_clen,a0),d1
  777.         cmp.l    d1,d7                ;offsets match?
  778.         bne    .write2
  779.         add.l    d0,d0
  780.         sub.l    (mfl_clen,a0),d0
  781. .write2        cmp.l    (dp_Arg3,a4),d0
  782.         blo    .write_direct
  783.     ;get memory if necessary
  784. .write_cache    move.l    (mfl_iocache,a0),d0
  785.         bne    .write_memok
  786.         move.l    d4,d0
  787.         moveq    #MEMF_ANY,d1
  788.         jsr    (_LVOAllocMem,a6)
  789.         move.l    (dp_Arg1,a4),a0            ;lock
  790.         move.l    d0,(mfl_iocache,a0)
  791.         beq    .write_direct
  792.     ;into cache
  793. .write_memok    move.l    (mfl_cpos,a0),d1
  794.         add.l    (mfl_clen,a0),d1
  795.         cmp.l    d1,d7                ;offsets match?
  796.         beq    .write_posok
  797.         tst.l    (mfl_clen,a0)            ;any data stored?
  798.         bne    .write_flush
  799.         move.l    d7,(mfl_cpos,a0)
  800. .write_posok    move.l    d0,a1
  801.         move.l    d4,d0
  802.         sub.l    (mfl_clen,a0),d0        ;free space in cache
  803.         beq    .write_flush
  804.         cmp.l    d0,d6
  805.         bhs    .write_4
  806.         move.l    d6,d0
  807. .write_4    add.l    (mfl_clen,a0),a1
  808.         add.l    d0,(mfl_clen,a0)
  809.         sub.l    d0,d6
  810.         add.l    d0,d7
  811.         move.l    d5,a0
  812. .write_cpy    move.b    (a0)+,(a1)+
  813.         subq.l    #1,d0
  814.         bne    .write_cpy
  815.         move.l    a0,d5
  816.         tst.l    d6
  817.         beq    .write_end
  818.     ;flush buffer
  819. .write_flush    move.l    (dp_Arg1,a4),a0            ;lock
  820.         move.l    (mfl_clen,a0),d0        ;len
  821.         move.l    (mfl_cpos,a0),d1        ;offset
  822.         move.l    (mfl_iocache,a0),a1        ;buffer
  823.         move.l    (fl_Key,a0),a0            ;name
  824.         jsr    (resload_SaveFileOffset,a2)
  825.         move.l    (dp_Arg1,a4),a0            ;lock
  826.         clr.l    (mfl_clen,a0)
  827.         clr.l    (mfl_cpos,a0)
  828.         bra    .write_cache
  829.     ;write without cache
  830. .write_direct    move.l    d6,d0                ;len
  831.         move.l    d7,d1                ;offset
  832.         move.l    (fl_Key,a0),a0            ;name
  833.         move.l    d5,a1                ;buffer
  834.         jsr    (resload_SaveFileOffset,a2)
  835. .write_end    move.l    (dp_Arg3,a4),d0            ;bytes written
  836.         bra    .reply1
  837.     ENDC
  838.  
  839. ;---------------
  840.  
  841. .a_findinput    moveq    #ACCESS_READ,d2        ;mode
  842.         bra    .a_findall
  843. .a_findupdate    moveq    #ACCESS_WRITE,d2    ;mode
  844. .a_findall
  845.     ;check exist and lock it
  846.         bsr    .getarg2
  847.         move.l    d7,d0            ;APTR lock
  848.         bsr    .getarg3
  849.         move.l    d7,d1            ;BSTR name
  850.         bsr    .lock
  851.         tst.l    d0            ;APTR lock
  852.         beq    .reply2
  853.     ;init fh
  854.         bsr    .getarg1
  855.         move.l    d7,a0            ;fh
  856.         move.l    d0,(fh_Arg1,a0)        ;using the lock we refer the filename later
  857.     ;return
  858.         moveq    #DOSTRUE,d0
  859.         bra    .reply1
  860.  
  861. .a_findoutput    bsr    .getarg2
  862.         move.l    d7,d0            ;APTR lock
  863.         bsr    .getarg3
  864.         move.l    d7,d1            ;BSTR name
  865.         bsr    .buildname
  866.         move.l    d0,d2            ;d2 = name
  867.         beq    .reply2
  868.     ;create an empty file
  869.         move.l    d2,a0
  870.         sub.l    a1,a1
  871.         moveq    #0,d0
  872.         jsr    (resload_SaveFile,a2)
  873.     ;free the name
  874.         move.l    d2,a1
  875.         move.l    -(a1),d0
  876.         jsr    (_LVOFreeMem,a6)
  877.         bra    .a_findupdate
  878.  
  879. ;---------------
  880.  
  881. .a_end
  882.     IFD DEBUG
  883.         move.l    (dp_Arg1,a4),a0        ;APTR lock
  884.         cmp.l    (fl_Task,a0),a5
  885.         bne    _debug4
  886.     ENDC
  887.     IFD IOCACHE
  888.     ;flush write buffer
  889.         move.l    (dp_Arg1,a4),a0        ;lock
  890.         move.l    (mfl_clen,a0),d0    ;len
  891.         beq    .end_nocache
  892.         move.l    (mfl_cpos,a0),d1    ;offset
  893.         move.l    (mfl_iocache,a0),a1    ;buffer
  894.         move.l    (fl_Key,a0),a0        ;name
  895.         jsr    (resload_SaveFileOffset,a2)
  896. .end_nocache
  897.     ENDC
  898.         move.l    (dp_Arg1,a4),d0        ;APTR lock
  899.         bsr    .unlock
  900.         moveq    #DOSTRUE,d0
  901.         bra    .reply1
  902.  
  903. ;---------------
  904.  
  905. .a_seek        move.l    (dp_Arg1,a4),a0        ;APTR lock
  906.         move.l    (dp_Arg2,a4),d2        ;offset
  907.         move.l    (dp_Arg3,a4),d1        ;mode
  908.     ;calculate new position
  909.         beq    .seek_cur
  910.         bmi    .seek_beg
  911. .seek_end    add.l    (mfl_fib+fib_Size,a0),d2
  912.         bra    .seek_chk
  913. .seek_cur    add.l    (mfl_pos,a0),d2
  914. .seek_beg
  915. .seek_chk
  916.     ;validate new position
  917.         cmp.l    (mfl_fib+fib_Size,a0),d2
  918.         bhi    .seek_err
  919.     ;set new
  920.         move.l    (mfl_pos,a0),d0
  921.         move.l    d2,(mfl_pos,a0)
  922.         bra    .reply1
  923. .seek_err    move.l    #-1,d0
  924.         move.l    #ERROR_SEEK_ERROR,d1
  925.         bra    .reply2
  926.  
  927. ;---------------
  928.  
  929.     IFGT KICKVERSION-36
  930. .a_fh_from_lock    bsr    .getarg1        ;handle
  931.         move.l    d7,a0
  932.         bsr    .getarg2        ;lock
  933.         move.l    d7,(fh_Arg1,a0)        ;using the lock we refer the filename later
  934.         moveq    #DOSTRUE,d0
  935.         bra    .reply1
  936.     ENDC
  937.  
  938. ;---------------
  939.  
  940.     IFGT KICKVERSION-36
  941. .a_examine_all    moveq    #DOSFALSE,d0
  942.         move.l    #ERROR_ACTION_NOT_KNOWN,d1
  943.         bra    .reply2
  944.     ENDC
  945.  
  946. ;---------------
  947. ; these functions get the respective arg converted from a BPTR to a APTR in D7
  948.  
  949. .getarg1    move.l    (dp_Arg1,a4),d7
  950.         lsl.l    #2,d7
  951.         rts
  952. .getarg2    move.l    (dp_Arg2,a4),d7
  953.         lsl.l    #2,d7
  954.         rts
  955. .getarg3    move.l    (dp_Arg3,a4),d7
  956.         lsl.l    #2,d7
  957.         rts
  958.  
  959. ;---------------
  960. ; convert c-string into bcpl-string
  961. ; IN:    a0 = CSTR
  962. ; OUT:    -
  963.  
  964. .bstr        movem.l    d0-d2,-(a7)
  965.         moveq    #-1,d0
  966.         move.b    (a0)+,d2
  967. .bstr_1        addq.l    #1,d0
  968.         move.b    d2,d1
  969.         move.b    (a0),d2
  970.         move.b    d1,(a0)+
  971.         bne    .bstr_1
  972.         sub.l    d0,a0
  973.         move.b    d0,(-2,a0)
  974.         movem.l    (a7)+,d0-d2
  975.         rts
  976.  
  977. ;---------------
  978. ; lock a disk object
  979. ; IN:    d0 = APTR lock
  980. ;    d1 = BSTR name
  981. ;    d2 = LONG mode
  982. ; OUT:    d0 = APTR lock
  983. ;    d1 = LONG errcode
  984.  
  985. .lock        movem.l    d4/a4,-(a7)
  986.     ;get name
  987.         bsr    .buildname
  988.         tst.l    d0
  989.         beq    .lock_quit
  990.         move.l    d0,d4            ;D4 = name
  991.     ;get memory for lock
  992.         move.l    #mfl_SIZEOF,d0
  993.         move.l    #MEMF_CLEAR,d1
  994.         jsr    (_LVOAllocMem,a6)
  995.         tst.l    d0
  996.         beq    .lock_nomem
  997.         move.l    d0,a4            ;A4 = myfilelock
  998.     ;special
  999.     IFD BOOTDOS
  1000.         move.l    d4,a0
  1001.         bsr    .specialfile
  1002.         tst.l    d0
  1003.         beq    .lock_nospec
  1004.         move.l    #ST_FILE,(mfl_fib+fib_DirEntryType,a4)
  1005.         move.l    d1,(mfl_fib+fib_Size,a4)
  1006.         bra    .lock_spec
  1007. .lock_nospec
  1008.     ENDC
  1009.     ;examine
  1010.         move.l    d4,a0            ;name
  1011.         lea    (mfl_fib,a4),a1        ;fib
  1012.         jsr    (resload_Examine,a2)
  1013.         tst.l    d0
  1014.         beq    .lock_notfound
  1015. .lock_spec
  1016.     ;set return values
  1017.         move.l    a4,d0
  1018.         moveq    #0,d1
  1019.     ;fill lock structure
  1020.         addq.l    #4,a4            ;fl_Link
  1021.         move.l    d4,(a4)+        ;fl_Key (name)
  1022.         move.l    d2,(a4)+        ;fl_Access
  1023.         move.l    a5,(a4)+        ;fl_Task (MsgPort)
  1024.         move.l    a3,(a4)+        ;fl_Volume
  1025. .lock_quit    movem.l    (a7)+,d4/a4
  1026. .rts        rts
  1027. .lock_notfound    move.l    #mfl_SIZEOF,d0
  1028.         move.l    a4,a1
  1029.         jsr    (_LVOFreeMem,a6)
  1030.         pea    ERROR_OBJECT_NOT_FOUND
  1031.         bra    .lock_err
  1032. .lock_nomem    pea    ERROR_NO_FREE_STORE
  1033.     ;on error free the name
  1034. .lock_err    move.l    d4,a1
  1035.         move.l    -(a1),d0
  1036.         jsr    (_LVOFreeMem,a6)
  1037.         move.l    (a7)+,d1
  1038.         moveq    #DOSFALSE,d0
  1039.         bra    .lock_quit
  1040.  
  1041. ;---------------
  1042. ; free a lock
  1043. ; IN:    d0 = APTR lock
  1044. ; OUT:    -
  1045.  
  1046. .unlock        tst.l    d0
  1047.         beq    .rts
  1048.         move.l    d0,a1
  1049.     IFD DEBUG
  1050.         cmp.l    (fl_Task,a1),a5
  1051.         bne    _debug4
  1052.         clr.l    (fl_Task,a1)
  1053.     ENDC
  1054.         move.l    (fl_Key,a1),-(a7)    ;name
  1055.     IFD IOCACHE
  1056.         move.l    (mfl_iocache,a1),-(a7)
  1057.     ENDC
  1058.         move.l    #mfl_SIZEOF,d0
  1059.         jsr    (_LVOFreeMem,a6)
  1060.     IFD IOCACHE
  1061.         move.l    (a7)+,d0
  1062.         beq    .unlock1
  1063.         move.l    d0,a1
  1064.         move.l    #IOCACHE,d0
  1065.         jsr    (_LVOFreeMem,a6)
  1066. .unlock1
  1067.     ENDC
  1068.         move.l    (a7)+,a1
  1069.         move.l    -(a1),d0
  1070.         jmp    (_LVOFreeMem,a6)
  1071.  
  1072. ;---------------
  1073. ; build name for disk object
  1074. ; IN:    d0 = APTR lock (can represent a directory or a file)
  1075. ;    d1 = BSTR name (an object name relative to the lock, may contain assign or volume in front)
  1076. ; OUT:    d0 = APTR name (size=-(d0), must be freed via exec.FreeMem)
  1077. ;    d1 = LONG errcode
  1078.  
  1079. .buildname    movem.l    d3-d7,-(a7)
  1080.         moveq    #0,d6            ;d6 = length path
  1081.         moveq    #0,d7            ;d7 = length name
  1082.     ;get length of lock
  1083.         tst.l    d0
  1084.         beq    .buildname_nolock
  1085.         move.l    d0,a0
  1086.     IFD DEBUG
  1087.         cmp.l    (fl_Task,a0),a5
  1088.         bne    _debug4
  1089.     ENDC
  1090.         move.l    (fl_Key,a0),a0
  1091.         move.l    a0,d4            ;d4 = ptr path
  1092.         moveq    #-1,d6
  1093. .buildname_cl    addq.l    #1,d6
  1094.         tst.b    (a0)+
  1095.         bne    .buildname_cl
  1096. .buildname_nolock
  1097.     ;get length of name
  1098.         move.l    d1,a0            ;BSTR
  1099.         move.b    (a0)+,d7        ;length
  1100.         beq    .buildname_noname
  1101.     ;remove trailing "/"
  1102.         cmp.b    #1,d7
  1103.         beq    .buildname_nots
  1104.         cmp.b    #"/",(-1,a0,d7.l)
  1105.         bne    .buildname_nots
  1106.         subq.l    #1,d7
  1107. .buildname_nots
  1108.     ;remove leading "xxx:"
  1109.         lea    (a0,d7.l),a1        ;end
  1110. .buildname_col    cmp.b    #":",-(a1)
  1111.         beq    .buildname_fc
  1112.         cmp.l    a0,a1
  1113.         bne    .buildname_col
  1114.         subq.l    #1,a1
  1115. .buildname_fc    addq.l    #1,a1
  1116.         sub.l    a1,d7
  1117.         add.l    a0,d7
  1118.         move.l    a1,d5            ;d5 = ptr name
  1119. .buildname_noname
  1120.     ;allocate memory for object name
  1121.         moveq    #1+1+4,d0        ;the possible seperator "/", 0 terminator, length
  1122.         add.l    d6,d0
  1123.         add.l    d7,d0
  1124.         move.l    d0,d3            ;d3 = memlen
  1125.         move.l    #MEMF_ANY,d1
  1126.         jsr    (_LVOAllocMem,a6)
  1127.         tst.l    d0
  1128.         beq    .buildname_mem
  1129.         move.l    d0,a0
  1130.         move.l    d3,(a0)+
  1131.         move.l    a0,d0            ;d0 = new object memory
  1132.     ;copy name
  1133.         moveq    #"/",d3            ;d3 = "/"
  1134.         move.l    d4,a1
  1135.         move.l    d6,d1
  1136.         beq    .buildname_name
  1137. .buildname_cp    move.b    (a1)+,(a0)+
  1138.         subq.l    #1,d1
  1139.         bne    .buildname_cp
  1140.     ;add seperator
  1141.         tst.l    d7
  1142.         beq    .buildname_ok
  1143.         move.b    d3,(a0)+
  1144.     ;copy path
  1145. .buildname_name    move.l    d5,a1
  1146.         move.l    d7,d1
  1147.         beq    .buildname_ok
  1148. .buildname_cn    move.b    (a1)+,(a0)+
  1149.         subq.l    #1,d1
  1150.         bne    .buildname_cn
  1151. .buildname_ok    clr.b    (a0)            ;terminate
  1152.     ;check for "//" (double slash) and trailing slash's
  1153.         move.l    d0,a0
  1154.         move.l    d0,a1
  1155.         cmp.b    (a0),d3
  1156.         beq    .buildname_inv        ;must not start with a "/"
  1157. .buildname_ds1    move.b    (a0)+,d1
  1158.         beq    .buildname_ds3
  1159.         cmp.b    d3,d1
  1160.         bne    .buildname_ds2
  1161.         bset    #0,d7            ;indicate slash
  1162.         beq    .buildname_ds3
  1163.     ;two slash
  1164.         subq.l    #1,a1            ;skip already written slash
  1165.         cmp.l    a1,d0
  1166.         bhs    .buildname_inv        ;already at beginning?
  1167. .buildname_ss    cmp.b    -(a1),d3
  1168.         beq    .buildname_ds3
  1169.         cmp.l    a1,d0
  1170.         bne    .buildname_ss
  1171.         bra    .buildname_ds1
  1172.     ;copy
  1173. .buildname_ds2    sf    d7            ;no slash
  1174. .buildname_ds3    move.b    d1,(a1)+
  1175.         bne    .buildname_ds1
  1176.         tst.b    d7
  1177.         beq    .buildname_sok
  1178.     ;trailing slash
  1179.         subq.l    #2,a1            ;skip already written slash and 0
  1180.         cmp.l    a1,d0
  1181.         bhs    .buildname_inv        ;already at beginning?
  1182. .buildname_ts1    cmp.b    -(a1),d3
  1183.         beq    .buildname_ts2
  1184.         cmp.l    a1,d0
  1185.         bne    .buildname_ts1
  1186. .buildname_ts2    clr.b    (a1)
  1187. .buildname_sok
  1188.     ;finish
  1189.         moveq    #0,d1            ;errorcode
  1190. .buildname_quit    movem.l    (a7)+,d3-d7
  1191.         rts
  1192.  
  1193. .buildname_inv    move.l    #ERROR_OBJECT_NOT_FOUND,d1
  1194.         bra    .buildname_err
  1195. .buildname_mem    move.l    #ERROR_NO_FREE_STORE,d1
  1196. .buildname_err    moveq    #DOSFALSE,d0
  1197.         bra    .buildname_quit
  1198.  
  1199. ;---------------
  1200. ; check for special internal files
  1201. ; IN:    a0 = CSTR name
  1202. ; OUT:    d0 = APTR filedata
  1203. ;    d1 = LONG filelength
  1204.  
  1205.     IFD BOOTDOS
  1206. .specialfile
  1207.         lea    (bootfile_ss,pc),a1
  1208.         move.l    a1,d0
  1209.         move.l    #bootfile_ss_e-bootfile_ss,d1
  1210.         lea    (bootname_ss,pc),a1
  1211.         bsr    .specfile_chk
  1212.         beq    .specfile_rts
  1213.  
  1214.         lea    (bootfile_exe,pc),a1
  1215.         move.l    a1,d0
  1216.         move.l    #bootfile_exe_e-bootfile_exe,d1
  1217.         lea    (bootname_exe,pc),a1
  1218.         bsr    .specfile_chk
  1219.         beq    .specfile_rts
  1220.  
  1221.         moveq    #0,d0
  1222.         rts
  1223.  
  1224. .specfile_chk    move.l    a0,-(a7)
  1225.  
  1226. .specfile_cmp    cmpm.b    (a0)+,(a1)+
  1227.         bne    .specfile_end
  1228.         tst.b    (-1,a0)
  1229.         bne    .specfile_cmp
  1230.  
  1231. .specfile_end    move.l    (a7)+,a0
  1232. .specfile_rts    rts
  1233.     ENDC
  1234.  
  1235. ;---------------
  1236.  
  1237.     CNOP 0,4
  1238. .volumename    dc.b    7,"WHDLoad",0        ;BSTR (here with the exception that it must be
  1239.                         ;0-terminated!)
  1240. .devicename    dc.b    "whdload.device",0
  1241. .handlername    dc.b    "DH0",0
  1242. .expansionname    dc.b    "expansion.library",0
  1243. _dosname    dc.b    "dos.library",0
  1244.  
  1245. ;---------------
  1246.  
  1247.     IFD BOOTDOS
  1248.     IFND BOOTFILENAME
  1249. BOOTFILENAME    MACRO
  1250.         dc.b    "WHDBoot.exe"
  1251.     ENDM
  1252.     ENDC
  1253.     CNOP 0,4
  1254. bootfile_exe    dc.l    $3f3,0,1,0,0,2,$3e9,2
  1255. bootfile_exe_j    jmp    $99999999        ;avoid optimizing!
  1256.         dc.w    0            ;pad to longword
  1257.         dc.l    $3f2
  1258. bootfile_exe_e
  1259. bootname_ss_b    dc.b    10            ;BSTR
  1260. bootname_ss    dc.b    "WHDBoot.ss",0        ;name of ':s/startup-sequence'
  1261. bootfile_ss    BOOTFILENAME
  1262.         dc.b    10
  1263. bootfile_ss_e
  1264. bootname_exe    BOOTFILENAME
  1265.         dc.b    0
  1266.     ENDC
  1267.  
  1268. ;---------------
  1269.  
  1270.     EVEN
  1271.